﻿//===============================================================================
// TRONSoft
//
// Shifter
//
//===============================================================================
// Copyright © Ton de Ron.
//
// All rights reserved.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//
//===============================================================================

using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Shifter.Utils;

namespace Shifter.Selectors
{
    public class PropertySelector : MultipleSelector<PropertyInfo>
    {
        public override IEnumerable<PropertyInfo> Select(IShifterContext context)
        {
            Assume.ArgumentNotNull(context, "context");

            var propertyList = new List<PropertyInfo>
            (
                context.TypeToResolve
                    .GetTypeInfo()
                    .DeclaredProperties
                    .Where(p => GetMethodCondition(context, p) || SetMethodCondition(context, p))
            );

            return propertyList.Where(property => property.IsDefined(typeof(InjectAttribute), false));
        }

        private static bool SetMethodCondition(IShifterContext context, PropertyInfo p)
        {
            return (p.SetMethod != null && (p.SetMethod.IsFamily 
                                         || p.SetMethod.IsPublic 
                                         || p.SetMethod.IsPrivate == context.Container.Options.ResolvePrivateMembers));
        }

        private static bool GetMethodCondition(IShifterContext context, PropertyInfo p)
        {
            return (p.GetMethod != null && (p.GetMethod.IsFamily 
                                         || p.GetMethod.IsPublic 
                                         || p.GetMethod.IsPrivate == context.Container.Options.ResolvePrivateMembers));
        }
    }
}